package com.ticket.sass.admin.annotation;

import cn.hutool.core.util.StrUtil;
import com.ticket.sass.admin.dto.input.WeekTimeInput;
import com.ticket.sass.admin.dto.input.coupons.CouponAddInput;
import com.ticket.sass.admin.dto.input.coupons.CouponUpdInput;
import com.ticket.sass.admin.dto.input.pricescheme.PriceSchemeAddInput;
import com.ticket.sass.admin.dto.input.pricescheme.PriceSchemeUpdInput;

import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.*;
import java.util.List;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = WeekTimeRange.WeekTimeRangeValidator.class)
@Documented
public @interface WeekTimeRange {
    String message() default "请填写限定时间范围";
    
    Class<?>[] groups() default {};
    
    Class<? extends Payload>[] payload() default {};
    
    class WeekTimeRangeValidator implements ConstraintValidator<WeekTimeRange, Object> {
        @Override
        public boolean isValid(Object value, ConstraintValidatorContext context) {
            if (value instanceof PriceSchemeAddInput) {
                PriceSchemeAddInput input = (PriceSchemeAddInput) value;
                return check(input.getAvailablePeriod(), input.getWeekTimes());
            }
            if (value instanceof PriceSchemeUpdInput) {
                PriceSchemeUpdInput input = (PriceSchemeUpdInput) value;
                return check(input.getAvailablePeriod(), input.getWeekTimes());
            }
            
            if (value instanceof CouponAddInput) {
                CouponAddInput input = (CouponAddInput) value;
                return check(input.getAvailablePeriod(), input.getWeekTimes());
            }
            if (value instanceof CouponUpdInput) {
                CouponUpdInput input = (CouponUpdInput) value;
                return check(input.getAvailablePeriod(), input.getWeekTimes());
            }
            return true;
        }
        
        private boolean check(Short availablePeriod, List<WeekTimeInput> weekTimes) {
            if (availablePeriod != null && availablePeriod == 0) {
                return true;
            } else if (availablePeriod != null && availablePeriod == 1) {
                return weekTimes != null && !weekTimes.isEmpty() && hasValidTimes(weekTimes);
            }
            return false;
        }
        
        private boolean hasValidTimes(List<WeekTimeInput> weekTimes) {
            for (WeekTimeInput weekTime : weekTimes) {
                List<WeekTimeInput.WeekTime> times = weekTime.getTimes();
                if (times != null && !times.isEmpty()) {
                    for (WeekTimeInput.WeekTime time : times) {
                        if (StrUtil.isNotEmpty(time.getStart()) && StrUtil.isNotEmpty(time.getEnd())) {
                            return true;
                        }
                    }
                }
            }
            return false;
        }
    }
}
